package com.nineclock.auth.config;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.nineclock.auth.entity.IntegrationAuthenticationEntity;
import com.nineclock.auth.processor.AuthenticationProcessor;
import com.nineclock.auth.threadlocal.IntegrationAuthenticationHolder;
import com.nineclock.auth.threadlocal.UserHolder;
import com.nineclock.common.constant.NcConstant;
import com.nineclock.common.entity.UserInfo;
import com.nineclock.common.enums.ResponseEnum;
import com.nineclock.common.exception.NcException;
import com.nineclock.common.utils.BeanHelper;
import com.nineclock.model.dto.SysCompanyUserDTO;
import com.nineclock.model.dto.SysRoleDTO;
import com.nineclock.model.dto.SysUserDTO;
import com.nineclock.system.feign.SysUserFeign;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;

import java.util.Collections;
import java.util.List;

@Component
public class UserDetailsServiceImpl implements UserDetailsService {

    @Autowired
    SysUserFeign userFeign;

    //注入  两个处理器
    @Autowired
    List<AuthenticationProcessor> processors;

    //明文密码为 123456
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {

        //从线程中获取IntegrationAuthenticationEntity 实体类对象
        IntegrationAuthenticationEntity entity = IntegrationAuthenticationHolder.get();
        //需要选择 使用哪种处理方案
        AuthenticationProcessor processor = null;
        if (processors != null && processors.size() > 0) {
            //循环判断 处理器， 选择要使用的处理器
            for (AuthenticationProcessor p : processors) {
                Boolean flag = p.support(entity);
                if (flag) {
                    processor = p;
                }
            }
        }
        //获取相应 认证方法需要的 UserDto对象
        SysUserDTO userDto = processor.authenticate(entity);

        //把userDto 转换为UserInfo
        UserInfo userInfo = BeanHelper.copyProperties(userDto, UserInfo.class);


        String clientId = entity.getAuthParameter("client_id");
        String companyId = entity.getAuthParameter("company_id");

        if (clientId.equalsIgnoreCase("pc_client")) {

            //一个企业,直接判断管理员后登录登录
            List<SysCompanyUserDTO> companyUserDTOList = userFeign.queryCompanyUser(null, userInfo.getId()).getData();
            //pc端,管理员登录
            if (CollectionUtil.isEmpty(companyUserDTOList)) {
                throw new NcException(ResponseEnum.USER_NOT_JOIN_COMPANY);
            }
            //判断是不是管理员,管理员才能登录
            if (!this.checkAdmin(companyUserDTOList)) {
                throw new NcException(ResponseEnum.USER_NOT_COMPANY_ADMIN);
            }
            if(companyUserDTOList.size() == 1){
                this.wrapper(userInfo, companyUserDTOList);
            }

            if (StrUtil.isNotEmpty(companyId)) {
                //多个企业,传递companyID
                List<SysCompanyUserDTO> companyUserDTOS = userFeign.queryCompanyUser(Long.valueOf(companyId), userDto.getId()).getData();

                if (CollectionUtil.isEmpty(companyUserDTOS)) {
                    throw new NcException(ResponseEnum.USER_NOT_JOIN_COMPANY);
                }
                if (!this.checkAdmin(companyUserDTOS)) {
                    throw new NcException(ResponseEnum.USER_NOT_COMPANY_ADMIN);
                }
                this.wrapper(userInfo, companyUserDTOS);
            }

        } else {
            //APP端,用户都可以登录
            if (StrUtil.isEmpty(companyId)){
                companyId = String.valueOf(userDto.getLastLoginCompanyId());
            }

            List<SysCompanyUserDTO> companyUserDTOS = userFeign.queryCompanyUser(Long.valueOf(companyId), userDto.getId()).getData();
            if (CollectionUtil.isNotEmpty(companyUserDTOS)) {
                wrapper(userInfo,companyUserDTOS);
            }

        }


        //把userInfo存储到当前线程
        UserHolder.set(userInfo);

        if (userDto != null) {
            //在内存中构建一个权限信息
            SimpleGrantedAuthority grantedAuthority = new SimpleGrantedAuthority("ROLE_ADMIN");
            //Collections.singletonList(grantedAuthority)  ；把当个对象 封装到集合中
            //创建UserDetails对象 并返回
            User user = new User(JSONUtil.toJsonStr(userInfo), userDto.getPassword(), Collections.singletonList(grantedAuthority));

            return user;
        }

        return null;
    }

    /**
     * 判断是否是管理员的方法
     *
     * @param companyUserDTOList
     * @return
     */
    private Boolean checkAdmin(List<SysCompanyUserDTO> companyUserDTOList) {
        for (SysCompanyUserDTO companyUserDTO : companyUserDTOList) {
            List<SysRoleDTO> roles = companyUserDTO.getRoles();
            if (CollectionUtil.isEmpty(roles)) {
                return false;
            }
            if(CollectionUtil.isNotEmpty(roles)){
                for (SysRoleDTO role : roles) {
                    if(role.getRoleName().startsWith(NcConstant.ADMIN_ROLE_PREFIX)){
                        return true;
                    }
                }
            }
        }

        return false;
    }
    /**
     * 把企业信息封装在userInfo中
     *
     * @param userInfo
     * @param companyUserDTOS
     */
    public void wrapper(UserInfo userInfo, List<SysCompanyUserDTO> companyUserDTOS) {
        if (companyUserDTOS != null && companyUserDTOS.size() == 1) {
            SysCompanyUserDTO companyUserDTO = companyUserDTOS.get(0);
            //企业信息
            userInfo.setCompanyId(companyUserDTO.getCompanyId());//企业id
            userInfo.setCompanyName(companyUserDTO.getCompanyName());//企业名称
            userInfo.setCompanyUserId(companyUserDTO.getId());//企业员工id
            userInfo.setDepartmentId(companyUserDTO.getDepartmentId());//部门id
            userInfo.setDepartmentName(companyUserDTO.getDepartmentName());//部门名称
            userInfo.setPost(companyUserDTO.getPost());//职务
            userInfo.setWorkNumber(companyUserDTO.getWorkNumber());//工号
            userInfo.setTimeEntry(companyUserDTO.getTimeEntry());//入职时间
            userInfo.setEnable(true);//是否可用
            //用户的权限
            if (!CollectionUtil.isEmpty(companyUserDTO.getGrantedAuthorities())) {
                userInfo.setGrantedAuthorities(companyUserDTO.getGrantedAuthorities());//权限信息
            }
        }
    }
}